﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace Eniux.Windows.EnterpriseLibrary.Commands
{
    /// <summary>
    /// 参数类
    /// </summary>
    /// <typeparam name="TParameter"></typeparam>
    public class CommandParameter<TParameter>
    {
        #region 变量

        /// <summary>
        /// 参数
        /// </summary>
        public TParameter CustomParameter { get; private set; } 

        #endregion

        #region 构造

        /// <summary>
        ///  构造
        /// </summary>
        /// <param name="parameter">参数</param>
        protected CommandParameter(TParameter parameter)
        {
            this.CustomParameter = parameter;
        } 

        #endregion

        #region 方法

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static CommandParameter<TParameter> Cast(object parameter)
        {
            var parameterToCast = parameter as CommandParameter<object>;
            if (parameterToCast == null)
            {
                throw new InvalidCastException(string.Format("Failed to case {0} to {1}",
                    parameter.GetType(), typeof(CommandParameter<object>)));
            }

            var castedParameter = new CommandParameter<TParameter>(
                (TParameter)parameterToCast.CustomParameter);

            return castedParameter;
        } 

        #endregion
    }

    /// <summary>
    /// 事件命令参数
    /// </summary>
    /// <typeparam name="TParameter"></typeparam>
    /// <typeparam name="TEventArgs"></typeparam>
    public class EventCommandParameter<TParameter, TEventArgs> : CommandParameter<TParameter>
        where TEventArgs : RoutedEventArgs
    {
        #region 变量 

        /// <summary>
        ///  路由事件
        /// </summary>
        public RoutedEvent RoutedEvent { get; private set; }

        /// <summary>
        /// 事件参数
        /// </summary>
        public TEventArgs EventArgs { get; private set; } 

        #endregion

        #region 构造

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <param name="routedEvent">路由</param>
        /// <param name="eventArgs">事件参数</param>
        public EventCommandParameter(
            TParameter parameter,
            RoutedEvent routedEvent,
            TEventArgs eventArgs)
            : base(parameter)
        {
            this.RoutedEvent = routedEvent;
            this.EventArgs = eventArgs;
        } 

        #endregion

        #region 方法

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public new static EventCommandParameter<TParameter, TEventArgs> Cast(object parameter)
        {
            var parameterToCast = parameter as EventCommandParameter<object, RoutedEventArgs>;
            if (parameterToCast == null)
            {
                throw new InvalidCastException(string.Format("Failed to case {0} to {1}",
                    parameter.GetType(), typeof(EventCommandParameter<object, RoutedEventArgs>)));
            }

            var castedParameter = new EventCommandParameter<TParameter, TEventArgs>(
                (TParameter)parameterToCast.CustomParameter,
                parameterToCast.RoutedEvent,
                (TEventArgs)parameterToCast.EventArgs);

            return castedParameter;
        } 

        #endregion
    }

    /// <summary>
    /// 属性命令参数
    /// </summary>
    /// <typeparam name="TParameter"></typeparam>
    /// <typeparam name="TValue"></typeparam>
    public class PropertyCommandParameter<TParameter, TValue> : CommandParameter<TParameter>
    {
        #region 变量

        /// <summary>
        /// 依赖属性
        /// </summary>
        public DependencyProperty Property { get; private set; }

        /// <summary>
        /// 属性值
        /// </summary>
        public TValue Value { get; private set; } 

        #endregion

        #region 构造

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <param name="property">依赖属性</param>
        /// <param name="value">属性值</param>
        public PropertyCommandParameter(
            TParameter parameter,
            DependencyProperty property,
            TValue value)
            : base(parameter)
        {
            this.Property = property;
            this.Value = value;
        } 

        #endregion

        #region 方法

        public new static PropertyCommandParameter<TParameter, TValue> Cast(object parameter)
        {
            var parameterToCast = parameter as PropertyCommandParameter<object, object>;
            if (parameterToCast == null)
            {
                throw new InvalidCastException(string.Format("Failed to case {0} to {1}",
                    parameter.GetType(), typeof(PropertyCommandParameter<object, object>)));
            }

            var castedParameter = new PropertyCommandParameter<TParameter, TValue>(
                (TParameter)parameterToCast.CustomParameter,
                parameterToCast.Property,
                (TValue)parameterToCast.Value);

            return castedParameter;
        } 

        #endregion
    }
}
